﻿using Studio77.RuneMaster.Core;
using Studio77.RuneMaster.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Studio77.RuneMaster.Utils
{
    public class EliminateLogicHelper
    {
        /// <summary>
        /// 找到所有能够消除的节点
        /// </summary>
        /// <returns></returns>
        public static List<RuneItemChangeInfo> FindEliminate(int[,] datas, ref EliminateStatus status)
        {
            List<RuneItemChangeInfo> resultSum = new List<RuneItemChangeInfo>(0);
            List<RuneItemChangeInfo> resultRight = new List<RuneItemChangeInfo>(5);
            List<RuneItemChangeInfo> resultDown = new List<RuneItemChangeInfo>(7);
            List<RuneItemChangeInfo> resultRightDown = new List<RuneItemChangeInfo>(5);
            List<RuneItemChangeInfo> resultLeftDown = new List<RuneItemChangeInfo>(5);

            //统计被计算消除过的单元格
            List<int> eliminateListRight = new List<int>();
            List<int> eliminateListDown = new List<int>();
            List<int> eliminateListRightDown = new List<int>();
            List<int> eliminateListLeftDown = new List<int>();

            for (int i = 0; i < GameStatics.RowCount; i++)
            {
                for (int j = 0; j < GameStatics.ColumnCount; j++)
                {
                    List<int> tempEliminateList = new List<int>();
                    

                    //向右找
                    tempEliminateList.Clear();
                    tempEliminateList.Add(i * GameStatics.ColumnCount + j);
                    resultRight.Clear();
                    resultRight.Add(new RuneItemChangeInfo() { StartX = i, StartY = j });
                    int count = 1;
                    int type = datas[i, j];
                    for (int k = j + 1; k < GameStatics.ColumnCount; k++)
                    {
                        int key = i * GameStatics.ColumnCount + k;
                        if (!eliminateListRight.Contains(key) && datas[i, k] != 0 && datas[i, k] == type)
                        {
                            tempEliminateList.Add(key);
                            RuneItemChangeInfo info = new RuneItemChangeInfo() { StartX = i, StartY = k };
                            resultRight.Add(info);
                            count++;
                        }
                        else
                        {
                            break;
                        }
                    }
                    if (count >= 4)
                    {
                        eliminateListRight.AddRange(tempEliminateList);
                        status.CompleteColors.Add(type);
                        status.CompleteDetails.Add(count);
                        foreach (var item in resultRight)
                        {
                            resultSum.Add(item);
                        }
                    }

                    //向下找
                    tempEliminateList.Clear();
                    tempEliminateList.Add(i * GameStatics.ColumnCount + j);
                    resultDown.Clear();
                    resultDown.Add(new RuneItemChangeInfo() { StartX = i, StartY = j });
                    count = 1;
                    type = datas[i, j];
                    if (type == 0)
                    {
                        continue;
                    }
                    for (int k = i + 1; k < GameStatics.RowCount; k++)
                    {
                        int key = k * GameStatics.ColumnCount + j;
                        if (!eliminateListDown.Contains(key) && datas[k, j] != 0 && datas[k, j] == type)
                        {
                            tempEliminateList.Add(key);
                            RuneItemChangeInfo info = new RuneItemChangeInfo() { StartX = k, StartY = j };
                            resultDown.Add(info);
                            count++;
                        }
                        else
                        {
                            break;
                        }
                    }
                    if (count >= 4)
                    {
                        eliminateListDown.AddRange(tempEliminateList);
                        status.CompleteColors.Add(type);
                        status.CompleteDetails.Add(count);
                        foreach (var item in resultDown)
                        {
                            resultSum.Add(item);
                        }
                    }


                    //左下角找
                    tempEliminateList.Clear();
                    tempEliminateList.Add(i * GameStatics.ColumnCount + j);
                    resultLeftDown.Clear();
                    resultLeftDown.Add(new RuneItemChangeInfo() { StartX = i, StartY = j });
                    count = 1;
                    int tempI = i + 1;
                    int tempJ = j - 1;
                    while (tempI < GameStatics.RowCount && tempJ >= 0)
                    {
                        int key = tempI * GameStatics.ColumnCount + tempJ;
                        if (!eliminateListLeftDown.Contains(key) && datas[tempI, tempJ] == type && datas[tempI, tempJ] != 0)
                        {
                            tempEliminateList.Add(key);
                            RuneItemChangeInfo info = new RuneItemChangeInfo() { StartX = tempI, StartY = tempJ };
                            resultLeftDown.Add(info);
                            count++;
                        }
                        else
                        {
                            break;
                        }

                        tempI++;
                        tempJ--;
                    }
                    if (count >= 4)
                    {
                        eliminateListLeftDown.AddRange(tempEliminateList);
                        status.CompleteColors.Add(type);
                        status.CompleteDetails.Add(count);
                        foreach (var item in resultLeftDown)
                        {
                            resultSum.Add(item);
                        }
                    }

                    //右下角找
                    tempEliminateList.Clear();
                    tempEliminateList.Add(i * GameStatics.ColumnCount + j);
                    resultRightDown.Clear();
                    resultRightDown.Add(new RuneItemChangeInfo() { StartX = i, StartY = j });
                    count = 1;
                    tempI = i + 1;
                    tempJ = j + 1;
                    while (tempI < GameStatics.RowCount && tempJ < GameStatics.ColumnCount)
                    {
                        int key = tempI * GameStatics.ColumnCount + tempJ;
                        if (!eliminateListRightDown.Contains(key) && datas[tempI, tempJ] == type && datas[tempI, tempJ] != 0)
                        {
                            tempEliminateList.Add(key);
                            RuneItemChangeInfo info = new RuneItemChangeInfo() { StartX = tempI, StartY = tempJ };
                            resultRightDown.Add(info);
                            count++;
                        }
                        else
                        {
                            break;
                        }

                        tempI++;
                        tempJ++;
                    }
                    if (count >= 4)
                    {
                        eliminateListRightDown.AddRange(tempEliminateList);
                        status.CompleteColors.Add(type);
                        status.CompleteDetails.Add(count);
                        foreach (var item in resultRightDown)
                        {
                            resultSum.Add(item);
                        }
                    }
                }
            }
            return resultSum;
        }

        /// <summary>
        /// 判断是否能够有消除
        /// </summary>
        /// <returns></returns>
        public static bool IsCanEliminate(int[,] datas)
        {
            for (int i = 0; i < GameStatics.RowCount; i++)
            {
                for (int j = 0; j < GameStatics.ColumnCount; j++)
                {
                    int count = 1;
                    //向右找
                    int type = datas[i, j];
                    if (type == 0)
                    {
                        continue;
                    }
                    for (int k = j + 1; k < GameStatics.ColumnCount; k++)
                    {
                        if (datas[i, k] != 0 && datas[i, k] == type)
                        {
                            count++;
                        }
                        else
                        {
                            break;
                        }
                    }
                    if (count >= 4)
                    {
                        return true;
                    }

                    //向下找
                    count = 1;
                    type = datas[i, j];
                    if (type == 0)
                    {
                        continue;
                    }
                    for (int k = i + 1; k < GameStatics.RowCount; k++)
                    {
                        if (datas[k, j] != 0 && datas[k, j] == type)
                        {
                            count++;
                        }
                        else
                        {
                            break;
                        }
                    }
                    if (count >= 4)
                    {
                        return true;
                    }

                    //左下角找
                    count = 1;
                    int tempI = i + 1;
                    int tempJ = j - 1;
                    while (tempI < GameStatics.RowCount && tempJ >= 0)
                    {
                        if (datas[tempI, tempJ] == type && datas[tempI, tempJ] != 0)
                        {
                            count++;
                        }
                        else
                        {
                            break;
                        }

                        tempI++;
                        tempJ--;
                    }
                    if (count >= 4)
                    {
                        return true;
                    }

                    //右下角找
                    count = 1;
                    tempI = i + 1;
                    tempJ = j + 1;
                    while (tempI < GameStatics.RowCount && tempJ < GameStatics.ColumnCount)
                    {
                        if (datas[tempI, tempJ] == type && datas[tempI, tempJ] != 0)
                        {
                            count++;
                        }
                        else
                        {
                            break;
                        }

                        tempI++;
                        tempJ++;
                    }
                    if (count >= 4)
                    {
                        return true;
                    }
                }
            }
            return false;
        }
    }
}
